package com.nexgo.payment.trans.login;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.nexgo.common.ByteUtils;
import com.nexgo.data.entity.RecvData;
import com.nexgo.oaf.apiv3.emv.EmvHandler;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.aop.annotation.ManageTransCondition;
import com.nexgo.payment.aop.annotation.RunOnWorkThread;
import com.nexgo.payment.api.ApiDeviceEngine;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.SysConstant;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.OperatorInfo;
import com.nexgo.payment.databases.PasswordInfo;
import com.nexgo.payment.entity.TransData;
import com.nexgo.payment.trans.AbsOnlinePresenter;
import com.nexgo.payment.util.AppUtils;
import com.nexgo.payment.util.BassInfoUtil;
import com.nexgo.payment.util.EncryptUtils;
import com.nexgo.payment.util.ParamFileManager;
import com.nexgo.payment.util.SPUtil;
import com.nexgo.payment.util.StringUtils;
import com.nexgo.payment.util.TransUtils;
import com.nexgo.payment.util.UIUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import java8.util.Optional;

import static com.google.common.base.Preconditions.checkNotNull;


/**
 * Created by xiaox on 2017/2/3.
 */
@ManageTransCondition
public class LoginPresenter extends AbsOnlinePresenter implements LoginContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(LoginPresenter.class.getSimpleName());

    private LoginContract.View mView;

    public LoginPresenter(@NonNull LoginContract.View view, @NonNull DataSource repository) {
        super(view, repository);
        mView = checkNotNull(view);
        mView.setPresenter(this);
    }

    @Override
    protected TransData getTransData() {
        TransData transData = new TransData();
        transData.setTransType(TransType.LOGIN);
        return transData;
    }

    @Override
    protected void onFirstAction() {

    }

    @Override
    @RunOnWorkThread
    protected void onTransSuccess(RecvData recvData) {
        if (null==recvData) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.login_fail)));
            return;
        }
//        wzp add
        postMainThread(() -> mView.setWaitingIndicator(true, null,App.sContext.getString(R.string.doing_something)));
//        43域 同步商户名称
        if (!TextUtils.isEmpty(recvData.getFeild43())) {
            try {
                byte[] name = ByteUtils.hexString2ByteArray(recvData.getFeild43());
                mRepository.setParamValue(PreferencesConstants.MERCHANT_NAME,new String(name, SysConstant.GBK).trim());
                mLog.debug("同步商户名称 {}",ByteUtils.byteArray2HexString(name));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
//            return;
        }
//
//        60同步后台参数下发

//        28域 清楚AID CAPK指令
        if (!TextUtils.isEmpty(recvData.getfield28())) {
            EmvHandler sdkEmvHandler = ApiDeviceEngine.getDefaultEmvHandler();
            String str = recvData.getfield28();
            if( "1".equals(str)){
                sdkEmvHandler.delAllCapk();
            }else if("2".equals(str)){
                sdkEmvHandler.delAllAid();
            }else if("4".equals(str)){
                sdkEmvHandler.delAllAid();
                sdkEmvHandler.delAllCapk();
            }

//            return;
        }
        /*if(!TextUtils.isEmpty(recvData.getAdditionalRespData())){
            byte[] value = ByteUtils.hexString2ByteArray(recvData.getAdditionalRespData());
//            mLog.debug("getAdditionalRespData value {} " ,recvData.getAdditionalRespData());
            PinPad sdkPinPad = ApiDeviceEngine.getInstance().getPinPad();
            boolean isDes = "0".equals(mRepository.getParamValue(PreferencesConstants.MASTER_KEY_ALGORITHM));
            boolean isTrackEncrypt = "1".equals(mRepository.getParamValue(PreferencesConstants.TRACK_ENCRYPTED));
            int mKeyIdx = Integer.parseInt(StringUtils.firstNonEmpty(mRepository.getParamValue(PreferencesConstants.MASTER_KEY_INDEX), "0"));
            byte[] tpk, tak, tdk;
            byte[] tpkCkv, takCkv, tdkCkv;
            byte[] ckv;
            boolean hasTdk = false;
            int sdkResult;
            if(value.length == 57){
                hasTdk = true;
            }
            mLog.debug("value.length {},hasTdk {}",value.length,hasTdk);
            if (!isDes) {
                tpk = Arrays.copyOfRange(value, 0, 16);
                tpkCkv = Arrays.copyOfRange(value, 16, 19);
            } else {
                tpk = Arrays.copyOfRange(value, 0, 8);
                tpkCkv = Arrays.copyOfRange(value, 8, 11);
            }
            mLog.debug("tpk {},tpkckv {}", ByteUtils.byteArray2HexString(tpk), ByteUtils.byteArray2HexString(tpkCkv));
            sdkResult = sdkPinPad.writeWKey(mKeyIdx, WorkKeyTypeEnum.PINKEY, tpk, tpk.length);
            if (sdkResult != SdkResult.Success) {
                postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tpk_fail)));
                return;
            }
            ckv = sdkPinPad.calcWKeyKCV(mKeyIdx, WorkKeyTypeEnum.PINKEY);
            mLog.debug("calc ckv {}", ByteUtils.byteArray2HexString(ckv));
            if (!ByteUtil.byteArrayCompare(tpkCkv, ckv,3)) {
                postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tpk_fail)));
                return;
            }
            if (!isDes) {
                tak = Arrays.copyOfRange(value, 19, 35);
                takCkv = Arrays.copyOfRange(value, 35, 38);
            } else {
                tak = Arrays.copyOfRange(value, 11, 19);
                takCkv = Arrays.copyOfRange(value, 19, 22);
            }
            mLog.debug("tak {},takckv {}", ByteUtils.byteArray2HexString(tak), ByteUtils.byteArray2HexString(takCkv));
            sdkResult = sdkPinPad.writeWKey(mKeyIdx, WorkKeyTypeEnum.MACKEY, tak, tak.length);
            if (sdkResult != SdkResult.Success) {
                postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tak_fail)));
                return;
            }
            ckv = sdkPinPad.calcWKeyKCV(mKeyIdx, WorkKeyTypeEnum.MACKEY);
            mLog.debug("calc ckv {}", ByteUtils.byteArray2HexString(ckv));
            if (!ByteUtil.byteArrayCompare(takCkv, ckv,3)) {
                postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tak_fail)));
                return;
            }
            if (!isDes && isTrackEncrypt && hasTdk) {
                tdk = Arrays.copyOfRange(value, 38, 54);
                tdkCkv = Arrays.copyOfRange(value, 54, 57);
                mLog.debug("tdk {},tdkckv {}", ByteUtils.byteArray2HexString(tdk), ByteUtils.byteArray2HexString(tdkCkv));
                sdkResult = sdkPinPad.writeWKey(mKeyIdx, WorkKeyTypeEnum.TDKEY, tdk, tdk.length);
                if (sdkResult != SdkResult.Success) {
                    postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                    postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tdk_fail)));
                    return;
                }
                ckv = sdkPinPad.calcWKeyKCV(mKeyIdx, WorkKeyTypeEnum.TDKEY);
                mLog.debug("calc ckv {}", ByteUtils.byteArray2HexString(ckv));
                if (!ByteUtil.byteArrayCompare(tdkCkv, ckv,3)) {
                    postMainThread(() -> mView.setWaitingIndicator(false, null, null));
                    postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tdk_fail)));
                    return;
                }
            }

        }*/
        if (!TextUtils.isEmpty(recvData.getDate()) && !TextUtils.isEmpty(recvData.getTime())) {
            //同步后台时间
            ApiDeviceEngine.getInstance().setSystemClock(App.sContext,
                    StringUtils.getCalenderField(Calendar.YEAR) + recvData.getDate() + recvData.getTime());
            //签到会同步时间，时间有可能大于或是小于目前机器上边的时间，导致UI记录双击延迟时间或变长
            UIUtils.clearLastClickEvent();
        }
        //取60域数据，保存批次号
            Optional.ofNullable(recvData.getField62())
                    .filter(s -> !TextUtils.isEmpty(s) && s.length() > 8)
                    .map(s -> s.substring(0, 6))
                    .ifPresent(s -> {
                        mLog.debug("批次号：{}", s);
                        mRepository.setParamValue(PreferencesConstants.BATCH_NUMBER, s);
                        mRepository.syncParamValue();
                    });
        String date = StringUtils.firstNonEmpty(recvData.getDate(), new SimpleDateFormat("MMdd", Locale.getDefault()).format(new Date()));
        mRepository.setParamValue(PreferencesConstants.LOGIN_DATE, date);
        mRepository.setParamValue(PreferencesConstants.IS_NEED_LOGIN, "0");
        mRepository.syncParamValue();
        if(!AppUtils.isWifi()) {
            checkBaseInfo();
        }
        postMainThread(() -> mView.setWaitingIndicator(false, null, null));
        postMainThread(() -> mView.showSuccessfullyLogin());
    }

    /*//lr add
    @Override
    @RunOnWorkThread
    protected void onTransSuccess(Obect recvData) {
//        wzp add
        postMainThread(() -> mView.setWaitingIndicator(true, null,App.sContext.getString(R.string.doing_something)));
//        43域 同步商户名称
        if (!TextUtils.isEmpty(recvData.getRecvData().getFeild43())) {
            try {
                byte[] name = ByteUtils.hexString2ByteArray(recvData.getRecvData().getFeild43());
                mRepository.setParamValue(PreferencesConstants.MERCHANT_NAME,new String(name, SysConstant.GBK).trim());
                mLog.debug("同步商户名称 {}",ByteUtils.byteArray2HexString(name));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
//            return;
        }
//
//        60同步后台参数下发

//        28域 清楚AID CAPK指令
        if (!TextUtils.isEmpty(recvData.getRecvData().getfield28())) {
            EmvHandler sdkEmvHandler = ApiDeviceEngine.getDefaultEmvHandler();
            String str = recvData.getRecvData().getfield28();
            if( "1".equals(str)){
                sdkEmvHandler.delAllCapk();
            }else if("2".equals(str)){
                sdkEmvHandler.delAllAid();
            }else if("4".equals(str)){
                sdkEmvHandler.delAllAid();
                sdkEmvHandler.delAllCapk();
            }

//            return;
        }
//        if(!TextUtils.isEmpty(recvData.getRecvData().getAdditionalRespData()))
        {
//            byte[] value = ByteUtils.hexString2ByteArray(recvData.getRecvData().getAdditionalRespData());
//            mLog.debug("getAdditionalRespData length {} value {} " ,value.length, ByteUtils.byteArray2HexString(value));
            PinPad sdkPinPad = ApiDeviceEngine.getInstance().getPinPad();
            boolean isDes = "0".equals(mRepository.getParamValue(PreferencesConstants.MASTER_KEY_ALGORITHM));
            boolean isTrackEncrypt = "1".equals(mRepository.getParamValue(PreferencesConstants.TRACK_ENCRYPTED));
            int mKeyIdx = Integer.parseInt(StringUtils.firstNonEmpty(mRepository.getParamValue(PreferencesConstants.MASTER_KEY_INDEX), "0"));
            byte[] tdk = new byte[16];
            byte[] tdkCkv = new byte[16];
            if (!isDes && isTrackEncrypt) {
//                System.arraycopy(value,0,tdk,0,16);
//                System.arraycopy(value,16,tdkCkv,0,3);
                tdk = recvData.getJsonRecData().getREQ_BODY().get("data_key").getBytes();
                tdkCkv = recvData.getJsonRecData().getREQ_BODY().get("data_key_check").getBytes();
                mLog.debug("index {} tdk {},tdkckv {}", mKeyIdx,ByteUtils.byteArray2HexString(tdk), ByteUtils.byteArray2HexString(tdkCkv));
                int sdkResult = sdkPinPad.writeWKey(mKeyIdx, WorkKeyTypeEnum.TDKEY, tdk, tdk.length);
                mLog.debug("writeWKey  sdkResult {}",sdkResult);
                if (sdkResult != SdkResult.Success) {
                    postMainThread(() -> mView.setWaitingIndicator(false, null,null));
                    postMainThread(() -> mView.showError(App.sContext.getString(R.string.login_fail)));
                    return;
                }

                byte[] ckv = sdkPinPad.calcWKeyKCV(mKeyIdx, WorkKeyTypeEnum.TDKEY);
                mLog.debug("calc ckv {}", ByteUtils.byteArray2HexString(ckv));
                if (!ByteUtil.byteArrayCompare(tdkCkv, ckv,3)) {
                    postMainThread(() -> mView.setWaitingIndicator(false, null,null));
                    postMainThread(() -> mView.showError(App.sContext.getString(R.string.load_tdk_fail)));
                    return;
                }
            }
        }
        if (!TextUtils.isEmpty(recvData.getRecvData().getDate()) && !TextUtils.isEmpty(recvData.getRecvData().getTime())) {
            //同步后台时间
            ApiDeviceEngine.getInstance().setSystemClock(App.sContext,
                    StringUtils.getCalenderField(Calendar.YEAR) + recvData.getRecvData().getDate() + recvData.getRecvData().getTime());
            //签到会同步时间，时间有可能大于或是小于目前机器上边的时间，导致UI记录双击延迟时间或变长
            UIUtils.clearLastClickEvent();
        }
        //取60域数据，保存批次号
        Optional.ofNullable(recvData.getRecvData().getField62())
                .filter(s -> !TextUtils.isEmpty(s) && s.length() > 8)
                .map(s -> s.substring(0, 6))
                .ifPresent(s -> {
                    mLog.debug("批次号：{}", s);
                    mRepository.setParamValue(PreferencesConstants.BATCH_NUMBER, s);
                    mRepository.syncParamValue();
                });
        String date = StringUtils.firstNonEmpty(recvData.getRecvData().getDate(), new SimpleDateFormat("MMdd", Locale.getDefault()).format(new Date()));
        mRepository.setParamValue(PreferencesConstants.LOGIN_DATE, date);
        mRepository.setParamValue(PreferencesConstants.IS_NEED_LOGIN, "0");
        mRepository.syncParamValue();
        postMainThread(() -> mView.setWaitingIndicator(false, null, null));
        postMainThread(() -> mView.showSuccessfullyLogin());
    }*/

    @Override
    public void login(String operator, String password) {
        //然后解析导入TempletPara.ini
        ParamFileManager.getInstance().parseTemplateParam();
        if (TextUtils.isEmpty(operator)) {
            postMainThread(() -> mView.showOperatorEmpty());
            return;
        }
        if (TextUtils.isEmpty(password)) {
            postMainThread(() -> mView.showPasswordEmpty());
            return;
        }
        operator = StringUtils.leftPad(operator, 2, '0');
        mLog.debug("操作员编号：{}", operator);
        //判断是否系统管理员
        if (TransUtils.isSystemOperator(operator)) {
            PasswordInfo info = mRepository.getPasswordInfo();
            if (!info.getManagePassword().equals(EncryptUtils.encryptSHA256ToString(password))) {
                postMainThread(() -> mView.showPasswordError());
                return;
            }

            postMainThread(() -> mView.login2SystemSetting());
            return;
        }
        //判断是否系统管理员
        if (TransUtils.isSystemOperator2(operator)) {
            PasswordInfo info = mRepository.getPasswordInfo();
            if (!info.getManagePassword().equals(EncryptUtils.encryptSHA256ToString(password))) {
                postMainThread(() -> mView.showPasswordError());
                return;
            }
            postMainThread(() -> mView.login3SystemSetting());
            return;
        }
        //记录当前操作员编号
        mRepository.setParamValue(PreferencesConstants.CURRENT_OPERATOR_NO, operator);
        mRepository.syncParamValue();
        //判断主管
        if (TransUtils.isAdminOperator(operator)) {
            PasswordInfo info = mRepository.getPasswordInfo();
            if (!info.getAdminPassword().equals(EncryptUtils.encryptSHA256ToString(password))) {
                postMainThread(() -> mView.showPasswordError());
                return;
            }
            postMainThread(() -> mView.showSuccessfullyLogin());
            return;
        }
        OperatorInfo info = mRepository.getOperator(operator);
        if (info == null) {
            postMainThread(() -> mView.showOperatorNotExist());
            return;
        }
        if (!info.getPassword().equals(EncryptUtils.encryptSHA256ToString(password))) {
            postMainThread(() -> mView.showPasswordError());
            return;
        }
        //开始签到
        postMainThread(() -> mView.showOnlineProc(mTransData, null));
    }
    private final String BASEINFO = "base_info";
    private void checkBaseInfo(){
        File file= new File("/data/data/com.nexgo.jhyzp"+"/shared_prefs","base_info.xml");
        if(!file.exists()) {
            List<String> BaseInfoList = BassInfoUtil.getAllBaseModeInfo(App.sContext);
            if(BaseInfoList != null){
                mLog.debug("mBaseList {}",BaseInfoList.size());
                saveBaseInfo(BaseInfoList);
            }
        }
    }

    private void saveBaseInfo(List<String> data) {
        SPUtil mSpUtil =  SPUtil.getInstance(App.sContext,BASEINFO);
        mSpUtil.cleanSharedPreferences();
        mSpUtil.putList(App.sContext,BASEINFO,data);
    }

}
